# Copyright 2008 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import os

from google.appengine.api import users
from google.appengine.ext import db
from google.appengine.ext.db import djangoforms

import django
from django import http
from django import shortcuts

class Array(db.Model):
  name = db.StringProperty(required=True)
  giver = db.UserProperty()
  vendor = db.StringProperty(required=True, choices=set(["IBM", "EMC", "HP"]))
  cache = db.IntegerProperty(required=True)
  on_sale = db.DateProperty()
  max_disks = db.IntegerProperty(required=True)
#  disk_support = db.ReferenceProperty(:
  description = db.TextProperty()
  url = db.URLProperty()
  created = db.DateTimeProperty(auto_now_add=True)
  modified = db.DateTimeProperty(auto_now=True)

class ArrayForm(djangoforms.ModelForm):
  class Meta:
    model = Array
    exclude = ['giver', 'created', 'modified']

class Disk(db.Model):
  capacity = db.IntegerProperty(required=True)
  giver = db.UserProperty()
  rpm = db.StringProperty(required=True, choices=set(["10k", "15k", "7200"]))
  type = db.StringProperty(required=True, choices=set(["SATA2", "FC", "SATA"]))

  description = db.TextProperty()
  url = db.URLProperty()
  created = db.DateTimeProperty(auto_now_add=True)
  modified = db.DateTimeProperty(auto_now=True)

class DiskForm(djangoforms.ModelForm):
  class Meta:
    model = Disk
    exclude = ['giver', 'created', 'modified']

def respond(request, user, template, params=None):
  """Helper to render a response, passing standard stuff to the response.

  Args:
    request: The request object.
    user: The User object representing the current user; or None if nobody
      is logged in.
    template: The template name; '.html' is appended automatically.
    params: A dict giving the template parameters; modified in-place.

  Returns:
    Whatever render_to_response(template, params) returns.

  Raises:
    Whatever render_to_response(template, params) raises.
  """
  if params is None:
    params = {}
  if user:
    params['user'] = user
    params['sign_out'] = users.CreateLogoutURL('/')
    params['is_admin'] = (users.IsCurrentUserAdmin() and
                          'Dev' in os.getenv('SERVER_SOFTWARE'))
  else:
    params['sign_in'] = users.CreateLoginURL(request.path)
  if not template.endswith('.html'):
    template += '.html'
  return shortcuts.render_to_response(template, params)


def index(request):
  """Request / -- show all arrays."""
  user = users.GetCurrentUser()
  arrays = db.GqlQuery('SELECT * FROM Array ORDER BY created DESC')
  return respond(request, user, 'list', {'arrays': arrays})
  disks = db.GqlQuery('SELECT * FROM Disk ORDER BY created DESC')
  return respond(request, user, 'list', {'disks': disks})

def edit_array(request, array_id):
  """Create or edit a array.  GET shows a blank form, POST processes it."""
  user = users.GetCurrentUser()
  if user is None:
    return http.HttpResponseForbidden('You must be signed in to add or edit a array')

  array = None
  if array_id:
    array = Array.get(db.Key.from_path(Array.kind(), int(array_id)))
    if array is None:
      return http.HttpResponseNotFound('No array exists with that key (%r)' %
                                       array_id)

  form = ArrayForm(data=request.POST or None, instance=array)

  if not request.POST:
    return respond(request, user, 'array', {'form': form, 'array': array})

  errors = form.errors
  if not errors:
    try:
      array = form.save(commit=False)
    except ValueError, err:
      errors['__all__'] = unicode(err)
  if errors:
    return respond(request, user, 'array', {'form': form, 'array': array})

  if not array.giver:
    array.giver = user
  array.put()

  return http.HttpResponseRedirect('/')

def edit_disk(request, disk_id):
  """Create or edit a disk.  GET shows a blank form, POST processes it."""
  user = users.GetCurrentUser()
  if user is None:
    return http.HttpResponseForbidden('You must be signed in to add or edit a disk')

  disk = None
  if disk_id:
    disk = Disk.get(db.Key.from_path(Disk.kind(), int(disk_id)))
    if disk is None:
      return http.HttpResponseNotFound('No disk exists with that key (%r)' %
                                       disk_id)

  form = DiskForm(data=request.POST or None, instance=disk)

  if not request.POST:
    return respond(request, user, 'disk', {'form': form, 'disk': disk})

  errors = form.errors
  if not errors:
    try:
      disk = form.save(commit=False)
    except ValueError, err:
      errors['__all__'] = unicode(err)
  if errors:
    return respond(request, user, 'disk', {'form': form, 'disk': disk})

  if not disk.giver:
    disk.giver = user
  disk.put()

  return http.HttpResponseRedirect('/')

def new_array(request):
  """Create a array.  GET shows a blank form, POST processes it."""
  return edit_array(request, None)

def new_disk(request):
  """Create a disk.  GET shows a blank form, POST processes it."""
  return edit_disk(request, None)
